home *** CD-ROM | disk | FTP | other *** search
/ The Very Best of Atari Inside / The Very Best of Atari Inside 1.iso / mint / mntlib43 / mntlib / getgroup.c < prev    next >
C/C++ Source or Header  |  1993-07-06  |  3KB  |  141 lines

  1. /*
  2.  * FILE
  3.  *    getgroup.c
  4.  *
  5.  * PURPOSE
  6.  *    get the groups the current user is in
  7.  *
  8.  * AUTHORS
  9.  *    written by Ole Arndt and placed in the public domain :-)
  10.  *
  11.  * BUGS
  12.  *    under BSD user has access to all groups he is in at the same time
  13.  *    under MiNT there is only one valid group at a time.
  14.  *  so for suid programs this function gives you the groups you can
  15.  *    switch to for your real user.
  16.  *
  17.  * $Revision$   $Date$    $Author$
  18.  * 1        01JUL1993 entropy@terminator.rs.itd.umich.edu
  19.  *
  20.  * $Log$
  21.  *    Rev. 1: Allow for querying number of groups with
  22.  *         getgroups(0, (gid_t *) NULL) for POSIX compilance.
  23.  *        Only return alternate groups if the user could really
  24.  *        change groups (user has effective uid or gid of 0).
  25.  *        Use getpwuid(getuid()) instead of getlogin().
  26.  *        Act reasonably for TOS.
  27.  */
  28.  
  29. #include <stdio.h>
  30. #include <string.h>
  31. #include <types.h>
  32. #include <errno.h>
  33. #include <unistd.h>
  34. #include <grp.h>
  35. #include <pwd.h>
  36. #ifdef TEST
  37. #include <stdlib.h> /* for calloc() */
  38. #endif
  39.  
  40. extern int __mint;
  41.  
  42. int
  43. getgroups(gsetlen, grpset)
  44.   int     gsetlen;
  45.   gid_t   *grpset;
  46. {
  47.   struct group    *gentry;
  48.   int             numgroups;
  49.   struct passwd   *userpw;
  50.   int             i;
  51.   gid_t           currgid;
  52.  
  53.   if (!__mint)
  54.     return 0;
  55.  
  56.   currgid = getgid();
  57.   if (gsetlen) {
  58.     if (gsetlen < 0 || !grpset) {
  59.       errno = EINVAL;
  60.       return -1;
  61.     }
  62.     *grpset++ = currgid;
  63.   }
  64.  
  65.   if (geteuid() && getegid())
  66.     return 1;
  67.  
  68.   userpw = getpwuid(getuid());
  69.   if (!userpw) {
  70.     return -1;
  71.   }
  72.  
  73.   numgroups = 1;
  74.   setgrent();
  75.   while ((gentry = getgrent()) != NULL) {
  76.     for (i = 0; gentry->gr_mem[i]; i++) {
  77.       if (!strcmp(userpw->pw_name, gentry->gr_mem[i])
  78.           && (gentry->gr_gid != currgid)) {
  79.         ++numgroups;
  80.         if (gsetlen) {
  81.           if (numgroups > gsetlen) {
  82.             errno = EINVAL;
  83.             return -1;
  84.       }
  85.           *grpset++ = gentry->gr_gid;
  86.           break;
  87.         }
  88.       }
  89.     }
  90.   }
  91.   endgrent();
  92.   return numgroups;
  93. }
  94.  
  95. #ifdef TEST
  96.  
  97. int
  98. main(void)
  99. {
  100.   int ngroups;
  101.   int num, i;
  102.   gid_t *grps;
  103.   struct passwd *userpw;
  104.  
  105.   ngroups = getgroups(0, (gid_t *) NULL);
  106.   if (ngroups < 0) {
  107.     perror("getgroups() first call failed");
  108.     exit(2);
  109.   }
  110.   printf("first call to getgroups(): %d\n", ngroups);
  111.   grps = (gid_t *) calloc(ngroups, sizeof(gid_t));
  112.   if (!grps) {
  113.     perror("calloc() failed");
  114.     exit(2);
  115.   }
  116.   num = getgroups(ngroups, grps);
  117.   if (num < 0) {
  118.     perror("getgroups() second call failed");
  119.     exit(2);
  120.   }
  121.   printf("second call to getgroups(): %d\n", num);
  122.   if (ngroups != num) {
  123.     printf("getgroups() results do not match\n");
  124.     exit(2);
  125.   }
  126.  
  127.   userpw = getpwuid(getuid());
  128.   printf("User %s is in the following groups: ", userpw->pw_name);
  129.  
  130.   if (num == 0)
  131.     printf("none");
  132.   else
  133.     for( i = 0; i < num; i++)
  134.       printf("%d ", grps[i]);
  135.   printf(".\n");
  136.  
  137.   return 0;
  138. }
  139.  
  140. #endif
  141.